package grow

import (
	"server/game/cache"
	"server/game/itypes"
	"server/game/model"
	"server/share/config"

	"github.com/hwcer/cosgo/registry"
	"github.com/hwcer/cosgo/slice"
	"github.com/hwcer/updater/dataset"
	"github.com/hwcer/yyds/context"
	"github.com/hwcer/yyds/errors"
)

func init() {
	Register(&like{})
}

// 芯片 装备
type like struct {
}

func (this *like) Caller(node *registry.Node, handle *context.Context) interface{} {
	f := node.Method().(func(*like, *context.Context) interface{})
	return f(this, handle)
}

/**
 * @name likeUp
 * @param string key 唯一ID
 * @param json costData 消耗物品 json格式 物品id:num
 * 增加好感度
 */
func (this *like) LikeUp(c *context.Context) any {
	args := struct {
		Key      string          `json:"key" bson:"key"`
		CostData map[int32]int32 `json:"costData" bson:"costData"`
	}{
		CostData: make(map[int32]int32),
	}
	if args.Key == "" || len(args.CostData) == 0 {
		return errors.ErrArgEmpty
	}
	for k, v := range args.CostData {
		if k <= 0 || v < 1 {
			return errors.ErrArgEmpty
		}
	}

	if err := c.Bind(&args); err != nil {
		return err
	}
	items := cache.GetItems(c.Player.Updater)
	data := items.Get(args.Key)
	if data == nil {
		return errors.ErrDataNotExists
	}
	unitConfig := config.Data.Unit[data.IID]
	if unitConfig == nil {
		return errors.ErrDataNotExists
	}

	collectColl := c.Player.Collection(config.ITypeCollect)
	collectColl.Select(data.IID)
	if err := c.Player.Updater.Data(); err != nil {
		return err
	}

	mood := &model.UnitMood{}
	if err := data.Attach.Unmarshal(model.AttachUnitMood, mood); err != nil {
		return err
	}
	preferItemConfig := config.Data.PreferItem[unitConfig.Race]
	if preferItemConfig == nil {
		return c.Errorf(0, "config PreferItem Not Exist:%v", unitConfig.Race)
	}
	var expNum int32 = 0
	var moodNum int32 = 0
	for k, v := range args.CostData {
		giftConfig := config.Data.UnitGiftItem[k]
		if giftConfig == nil {
			return c.Errorf(0, "config UnitGiftItem Not Exist:%v", k)
		}
		if v <= 0 {
			continue
		}
		if slice.Has(preferItemConfig.GiftID, k) {
			expNum += giftConfig.AddExp * v * 2
		} else {
			expNum += giftConfig.AddExp * v
		}
		moodNum += giftConfig.AddMood * v
		c.Player.Sub(k, v)
	}

	mood.AddVal(moodNum)

	if i := collectColl.Get(data.IID); i != nil {
		collectData := i.(*model.Collect)
		collectData.AddExp(expNum)
		up := dataset.Update{}
		up["Lv"] = collectData.Lv
		up["Exp"] = collectData.Exp
		collectColl.Set(collectData.OID, up)
	}

	items.SetAttach(args.Key, model.AttachUnitMood, mood)
	return nil
}

/**
 * @name touchUnit
 * @param int id 好感度组ID 角色配置ID
 * 触摸增加好感度
 */
func (this *like) TouchUnit(c *context.Context) any {
	id := c.GetInt32("id")
	if id <= 0 {
		return errors.ErrArgEmpty
	}
	unitConfig := config.Data.Unit[id]
	if unitConfig == nil {
		return errors.ErrConfigEmpty
	}

	touchMaxTimes := config.Data.Base["touchMaxTimes"]
	if touchMaxTimes.Val > 0 {
		daily := itypes.Daily.Handle(c.Player.Updater)
		touchTime := daily.GetInt32("touchTime")
		if touchTime > touchMaxTimes.Val {
			return c.Error("touchTime too big")
		}
		daily.Add("touchTime", 1)
	}

	collectColl := c.Player.Collection(config.ITypeCollect)
	collectColl.Select(id)
	if err := c.Player.Updater.Data(); err != nil {
		return err
	}
	var collectData *model.Collect
	if i := collectColl.Get(id); i != nil {
		collectData = i.(*model.Collect)
	} else {
		return nil //静默处理 TODO
		//return c.Error("collect not exist")
	}
	touchFavorability := config.Data.Base["touchFavorability"]
	if touchFavorability.Val > 0 {
		collectData.AddExp(touchFavorability.Val)
		up := dataset.Update{}
		up["Lv"] = collectData.Lv
		up["Exp"] = collectData.Exp
		collectColl.Set(collectData.OID, up)
	}
	return nil
}

/**
 * @name getLikeReward
 * @param int id 好感度组ID
 * 获取好感度奖励
 */
func (this *like) GetLikeReward(c *context.Context) any {
	id := c.GetInt32("id")
	if id <= 0 {
		return errors.ErrArgEmpty
	}
	unitConfig := config.Data.Unit[id]
	if unitConfig == nil {
		return errors.ErrConfigEmpty
	}
	collectColl := c.Player.Collection(config.ITypeCollect)
	collectColl.Select(id)
	if err := c.Player.Updater.Data(); err != nil {
		return err
	}
	var collectData *model.Collect
	if i := collectColl.Get(id); i != nil {
		collectData = i.(*model.Collect)
	} else {
		return c.Error("collect not exist")
	}
	if collectData.Reward >= collectData.Lv {
		return nil
	}
	for i := collectData.Reward + 1; i <= collectData.Lv; i++ {
		collectData.Reward = i
		likeExp := config.Data.LikeExp[i]
		if likeExp != nil && int(unitConfig.Rare) < len(likeExp.Gift) {
			if k := likeExp.Gift[unitConfig.Rare]; k > 0 {
				c.Player.Add(k, 1)
			}
		}
	}
	collectColl.Set(collectData.OID, "Reward", collectData.Reward)
	return nil

}
